<template>
  <div class="horizontal-container">
    <div>
      <!-- 左边部分 -->
      <EntityClassAndEntityInstance @show-add-entity-dialog="showDialog = true" />
    </div>
    <!-- 中间内容区域 -->
    <div class="content-area">
      <textarea id="editor" v-model="form.content"></textarea>
    </div>
    <div>
      <!-- 右侧文档信息区域 -->
      <DocumentInfo />
    </div>
    <MatchEntityDialog v-model:visible="dialogVisible" @close="dialogVisible = false" />
    <BatchMatchDialog :visible="batchDialogVisible" @close="batchDialogVisible = false" />
    <AutoAnnotateDialog v-model:visible="autoAnnotateVisible" @close="autoAnnotateVisible = false" />
    <!-- 弹出框组件 -->
    <AddEntityDialog v-model="showDialog" />
  </div>
</template>

<script setup>
import { nextTick, onMounted, onBeforeUnmount, reactive, ref, watch } from 'vue'
import DocumentInfo from '@/views/demension/DocumentInfo.vue'
import EntityClassAndEntityInstance from '@/views/demension/EntityClassAndEntityInstance.vue'
import MatchEntityDialog from '@/views/demension/MatchEntityDialog.vue'
import BatchMatchDialog from '@/views/demension/BatchMatchDialog.vue'
import AutoAnnotateDialog from '@/views/demension/AutoAnnotateDialog.vue'
import AddEntityDialog from '@/views/demension/AddEntityDialog.vue'
import { useEditorStore } from '@/store/editor'
import axios from '@/plugins/axios'
import { ElMessage, ElLoading } from 'element-plus'
import { debounce, throttle } from 'lodash-es'
import { createEntityInstance, deleteEntityInstance, deleteEntityInstancesByEntityId, getEntityInstances, updateEntityInstancesByEntityId, updateEntityInstance } from '@/api/entityApi'

// 添加字符串哈希函数，用于检测内容变化
function hashString(str) {
  let hash = 0;
  if (str.length === 0) return hash;
  for (let i = 0; i < str.length; i++) {
    const char = str.charCodeAt(i);
    hash = ((hash << 5) - hash) + char;
    hash = hash & hash; // Convert to 32bit integer
  }
  return hash;
}

// 使用编辑器状态管理
const editorStore = useEditorStore()

const form = reactive({
  content: ''
})
const dialogVisible = ref(false)
const batchDialogVisible = ref(false)
const autoAnnotateVisible = ref(false)
const showDialog = ref(false)

// 创建防抖后的保存函数
const debouncedSaveContent = debounce((content) => {
  // 从editorStore获取文档ID
  const documentId = editorStore.documentInfo?.id
  console.log('[实体标注] 要保存内容到后端的文档ID:', documentId)
  if (!documentId) {
    console.error('[实体标注] 未找到文档ID，无法保存内容')
    return
  }

  // 发送请求到后端保存内容
  axios.post('/update_document_content', {
    documentId: documentId,
    content: content
  })
    .then(response => {
      if (response.data.code === 200) {
        console.log('[实体标注] 文档内容保存成功')
      } else {
        console.error('[实体标注] 文档内容保存失败:', response.data.message)
      }
    })
    .catch(error => {
      console.error('[实体标注] 保存文档内容请求失败:', error)
    })
}, 1000);

// 动态引入 TinyMCE
const loadTinyMCE = () => {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script')
    script.src = '/tinymce/tinymce.min.js'
    script.onload = resolve
    script.onerror = reject
    document.head.appendChild(script)
  })
}

// 添加动态引入 LeaderLine 的函数
const loadLeaderLine = () => {
  return new Promise((resolve, reject) => {
    // 如果已经加载，直接返回
    if (window.LeaderLine) {
      console.log('[实体标注] LeaderLine库已存在，无需重新加载');
      resolve(window.LeaderLine);
      return;
    }

    console.log('[实体标注] 开始加载LeaderLine库...');

    // 检查是否已经有script标签在加载
    const existingScript = document.querySelector('script[src*="leader-line"]');
    if (existingScript) {
      console.log('[实体标注] 发现正在加载的LeaderLine脚本，等待加载完成');
      existingScript.onload = () => {
        console.log('[实体标注] 现有LeaderLine脚本加载完成');
        if (window.LeaderLine) {
          resolve(window.LeaderLine);
        } else {
          reject(new Error('LeaderLine库加载完成但未定义'));
        }
      };
      existingScript.onerror = () => {
        reject(new Error('现有LeaderLine脚本加载失败'));
      };
      return;
    }

    // 尝试使用本地文件路径
    const script = document.createElement('script');
    script.src = '/leader-line.min.js'; // 尝试使用本地文件
    script.async = true;

    script.onload = () => {
      console.log('[实体标注] LeaderLine库加载成功');
      if (window.LeaderLine) {
        resolve(window.LeaderLine);
      } else {
        reject(new Error('LeaderLine库加载完成但未定义'));
      }
    };
    script.onerror = () => {
      console.error('[实体标注] 本地LeaderLine库加载失败，尝试使用CDN');
      // 尝试使用CDN
      const cdnScript = document.createElement('script');
      cdnScript.src = 'https://cdn.jsdelivr.net/npm/leader-line@1.0.7/leader-line.min.js';
      cdnScript.async = true;

      cdnScript.onload = () => {
        console.log('[实体标注] LeaderLine库从CDN加载成功');
        if (window.LeaderLine) {
          resolve(window.LeaderLine);
        } else {
          reject(new Error('LeaderLine库从CDN加载完成但未定义'));
        }
      };
      cdnScript.onerror = () => {
        console.error('[实体标注] CDN LeaderLine库加载失败，尝试使用备用CDN');
        // 尝试使用备用CDN
        const backupScript = document.createElement('script');
        backupScript.src = 'https://unpkg.com/leader-line@1.0.7/leader-line.min.js';
        backupScript.async = true;

        backupScript.onload = () => {
          console.log('[实体标注] LeaderLine库从备用CDN加载成功');
          if (window.LeaderLine) {
            resolve(window.LeaderLine);
          } else {
            reject(new Error('LeaderLine库从备用CDN加载完成但未定义'));
          }
        };
        backupScript.onerror = () => {
          reject(new Error('LeaderLine库从备用CDN加载失败'));
        };

        document.head.appendChild(backupScript);
      };

      document.head.appendChild(cdnScript);
    };

    document.head.appendChild(script);
  });
};

// 更新实体标记函数，确保颜色一致性
const updateEntityMarkings = (editor) => {
  // 添加计时开始
  console.time('updateEntityMarkings');

  // 获取内容
  const content = editor.getContent();
  console.log('[实体标注] 更新实体标记函数，获取内容:', content);

  // 添加内容哈希检查，避免重复解析相同内容
  const contentHash = hashString(content);
  const lastMarkingsHash = editor._lastMarkingsHash;

  if (contentHash === lastMarkingsHash && contentHash !== null) {
    console.log('内容未变化，跳过实体标记更新');
    console.timeEnd('updateEntityMarkings');
    return;
  }

  // 存储新的哈希值
  editor._lastMarkingsHash = contentHash;

  // 使用更高效的DOM解析和查询
  const parser = new DOMParser();
  const doc = parser.parseFromString(content, 'text/html');

  // 直接使用属性选择器找到所有实体span，效率更高
  const entitySpans = doc.querySelectorAll('span.entity[data-entity-id]');

  // 使用Map替代普通对象，性能更好
  const entityCounts = new Map();
  const entityTexts = new Map();
  const checkedStatus = new Map();

  // 获取文档ID
  const documentId = editorStore.documentInfo?.id;

  // 创建数组用于存储实体实例数据，预先分配容量
  const entityInstances = [];

  // 创建Set存储唯一文本，避免重复
  const uniqueTexts = new Set();

  // 批量处理DOM元素
  entitySpans.forEach(span => {
    const entityId = span.getAttribute('data-entity-id');
    if (!entityId) return;

    // 初始化Map条目
    if (!entityCounts.has(entityId)) {
      entityCounts.set(entityId, 0);
      entityTexts.set(entityId, []);
      checkedStatus.set(entityId, []);
    }

    // 增加计数
    entityCounts.set(entityId, entityCounts.get(entityId) + 1);

    // 处理文本内容
    const text = span.textContent;
    const textKey = `${entityId}:${text}`;

    if (text && text.trim() && !uniqueTexts.has(textKey)) {
      uniqueTexts.add(textKey);
      entityTexts.get(entityId).push(text);

      // 收集检查状态
      const isChecked = span.getAttribute('data-checked') !== 'false';
      checkedStatus.get(entityId).push(isChecked);

      // 为每个实体实例创建数据对象
      if (documentId) {
        // 通过entityId获取对应实体类的颜色
        const backgroundColor = editorStore.getEntityColor(entityId);

        entityInstances.push({
          id: `${entityId}_${entityCounts.get(entityId)}`,
          entityId: entityId,
          documentId: documentId,
          text: text,
          isChecked: isChecked,
          style: { 'background-color': backgroundColor }
        });
      }
    }
  });

  // 更新editorStore中的实体实例数据 - 只在必要时更新
  if (documentId && entityInstances.length > 0) {
    // 转换Map为普通对象用于全局更新函数
    const entityCountsObj = {};
    const entityTextsObj = {};
    const checkedStatusObj = {};

    entityCounts.forEach((count, id) => {
      entityCountsObj[id] = count;
    });

    entityTexts.forEach((texts, id) => {
      entityTextsObj[id] = texts;
    });

    checkedStatus.forEach((statuses, id) => {
      checkedStatusObj[id] = statuses;
    });

    // 批量更新editorStore
    editorStore.setEntityInstances(entityInstances);

    // 如果存在全局更新方法，则调用它来更新实体标记数量和标注文本
    if (typeof window.updateEntityMarkedCount === 'function') {
      window.updateEntityMarkedCount(entityCountsObj, entityTextsObj, checkedStatusObj);
      console.log('已更新实体标记数量', entityCountsObj);
    } else {
      console.warn('未找到全局更新方法 updateEntityMarkedCount');
    }
  }

  console.timeEnd('updateEntityMarkings');
};

// 使用节流函数包装更新函数
const throttledUpdateEntityMarkings = throttle(updateEntityMarkings, 200);

// 使用防抖函数包装更新函数
const debouncedUpdateEntityMarkings = debounce(updateEntityMarkings, 300);

// 获取所有可能的关系类型文本
const getRelationTypes = () => {
  // 从localStorage获取关系类定义
  try {
    const storedRelations = localStorage.getItem('relations');
    if (storedRelations) {
      const relations = JSON.parse(storedRelations);
      // 提取所有关系类型的文本
      return relations.map(relation => relation.text || '').filter(text => text);
    }
  } catch (error) {
    console.error('[实体标注] 获取关系类型文本时出错:', error);
  }
  // 默认关系类型列表
  return [];
};

// 清理编辑器内容中可能存在的关系文本标签
const cleanupRelationLabelsInContent = (editor) => {
  if (!editor) return;

  // 获取当前编辑器内容
  const content = editor.getContent();

  // 获取关系类型文本列表
  const relationTypes = getRelationTypes();
  console.log('[结构标注] 关系类型文本列表:', relationTypes);

  if (relationTypes.length === 0) return;

  // 使用DOMParser解析HTML内容
  const parser = new DOMParser();
  const doc = parser.parseFromString(content, 'text/html');

  // 查找所有p标签
  const paragraphs = doc.querySelectorAll('p');
  let hasChanges = false;

  // 遍历所有p标签
  paragraphs.forEach(p => {
    // 检查p标签是否有属性
    if (p.attributes.length === 0 || (p.attributes.length === 1 && p.hasAttribute('data-mce-style'))) {
      const textContent = p.textContent.trim();

      // 检查p标签内容是否完全匹配任何关系类型文本
      const matchesRelationType = relationTypes.some(relationType =>
        textContent === relationType || textContent.includes(relationType)
      );

      // 如果匹配关系类型文本，则删除该p标签
      if (matchesRelationType) {
        p.parentNode.removeChild(p);
        hasChanges = true;
        console.log('[结构标注] 删除了包含关系类型文本的p标签:', textContent);
      }
    }
  });

  // 如果有变化，更新编辑器内容
  if (hasChanges) {
    // 获取修改后的HTML
    const cleanedContent = new XMLSerializer().serializeToString(doc.documentElement);

    // 由于XMLSerializer会包含html和body标签，需要提取实际内容
    const bodyContentMatch = cleanedContent.match(/<body>([\s\S]*?)<\/body>/i);
    const bodyContent = bodyContentMatch ? bodyContentMatch[1] : cleanedContent;

    console.log('[结构标注] 清理了编辑器内容中的关系标签');

    // 使用静默模式设置内容，不触发事件
    // editor.setContent(bodyContent, { no_events: true });

    // 手动更新本地状态
    form.content = bodyContent;
    editorStore.setContent(bodyContent);
    localStorage.setItem('editorContent', bodyContent);

    // 重新提取段落结构，使用节流版本
    setTimeout(() => throttledExtractParagraphs(editor), 10);
  }
};

// 上传 JSON 按钮的实现
const setupEditor = (editor) => {
  editor.on('change NodeChange SetContent ObjectResized input keyup blur', () => {
    // 先清理内容中可能存在的关系标签
    cleanupRelationLabelsInContent(editor);

    form.content = editor.getContent(); // 监听编辑器内容变化并更新表单内容

    // 保存内容到后端
    debouncedSaveContent(form.content);

    // 使用防抖函数更新实体标记数量和标注文本
    debouncedUpdateEntityMarkings(editor);
  })

  // 创建自定义弹出框元素
  let entityPopup = null;

  // 初始化弹出框
  const initEntityPopup = () => {
    // 创建弹出框元素
    entityPopup = document.createElement('div');
    entityPopup.className = 'entity-popup';
    entityPopup.style.position = 'absolute';
    entityPopup.style.zIndex = '9999';
    entityPopup.style.backgroundColor = '#fff';
    entityPopup.style.boxShadow = '0 2px 5px rgba(0,0,0,0.2)';
    entityPopup.style.borderRadius = '4px';
    entityPopup.style.padding = '8px';
    entityPopup.style.display = 'none';
    document.body.appendChild(entityPopup);
  };

  // 显示弹出框
  const showEntityPopup = (x, y) => {
    if (!entityPopup) return;

    // 设置弹出框位置
    entityPopup.style.left = `${x}px`;
    entityPopup.style.top = `${y}px`;
    entityPopup.style.display = 'block';

    // 获取实体列表
    const entities = window.entities || [];

    // 清空弹出框内容
    entityPopup.innerHTML = '';

    // 添加标题
    const title = document.createElement('div');
    title.textContent = '标注实体';
    title.style.fontWeight = 'bold';
    title.style.marginBottom = '8px';
    title.style.borderBottom = '1px solid #eee';
    title.style.paddingBottom = '4px';
    entityPopup.appendChild(title);

    // 获取当前选中内容的节点
    const selectedNode = editor.selection.getNode();
    // 检查选中内容是否已经被标注为实体
    const isEntitySpan = selectedNode.tagName === 'SPAN' && selectedNode.classList.contains('entity');
    // 如果已标注，获取当前实体ID
    const currentEntityId = isEntitySpan ? selectedNode.getAttribute('data-entity-id') : null;

    // 添加实体按钮
    entities.forEach(entity => {
      const button = document.createElement('button');
      button.textContent = entity.text;
      button.title = entity.description || entity.text;
      button.style.margin = '2px';
      button.style.padding = '4px 8px';
      button.style.border = '1px solid #ddd';
      button.style.borderRadius = '3px';
      button.style.backgroundColor = '#f5f5f5';
      button.style.cursor = 'pointer';

      // 如果当前按钮对应的实体与已标注实体相同，添加特殊样式
      if (currentEntityId === entity.id) {
        button.style.border = '2px solid #409eff';
      }

      // 添加点击事件
      button.addEventListener('click', () => {
        // 获取文档ID
        const documentId = editorStore.documentInfo?.id;
        if (!documentId) {
          console.error('未找到文档ID，无法创建实体实例');
          ElMessage.error('未找到文档ID，无法保存实体标注');
          return;
        }

        if (isEntitySpan) {
          // 如果点击的是相同的实体按钮，则取消标注
          if (currentEntityId === entity.id) {
            // 获取原始内容
            const originalContent = selectedNode.textContent;

            // 尝试从数据库删除实体实例
            const instanceId = selectedNode.getAttribute('data-instance-id');
            if (instanceId) {
              deleteEntityInstance(documentId, instanceId)
                .then(response => {
                  if (response.data.code === 200) {
                    ElMessage.success('成功从数据库删除实体实例');
                    // 从editorStore中删除实体实例
                    editorStore.deleteEntityInstance(instanceId);
                    // 强制标记实体实例数据已更新
                    editorStore.markEntityInstancesUpdated();
                  } else {
                    ElMessage.error('从数据库删除实体实例失败:', response.data.message);
                  }
                })
                .catch(error => {
                  ElMessage.error('删除实体实例请求失败:', error);
                });
            }

            // 替换为普通文本
            editor.selection.select(selectedNode);
            editor.selection.setContent(originalContent);

            // 重置编辑器内容哈希值，强制下次更新
            editor._lastMarkingsHash = null;

            // 立即更新实体标记数量和标注文本，使用非防抖版本确保立即执行
            setTimeout(() => updateEntityMarkings(editor), 0);
          } else {
            // 如果点击的是不同的实体按钮，则更换标注
            const originalContent = selectedNode.textContent;
            // 获取实体颜色，确保一致性
            const backgroundColor = editorStore.getEntityColor(entity.id);

            // 创建新的实体实例并发送到后端
            const instanceId = `${entity.id}_${Date.now()}`;
            const instanceData = {
              id: instanceId,
              text: originalContent,
              documentId: documentId,
              entity_id: entity.id,
              isChecked: true
            };

            createEntityInstance(instanceData)
              .then(response => {
                if (response.data.code === 200) {
                  console.log('实体实例创建成功:', response.data);
                  // 添加到编辑器的状态
                  editorStore.addEntityInstance(instanceData);

                  // 标记实体实例已更新，或直接触发重新加载
                  editorStore.markEntityInstancesUpdated();
                  // 或者直接重新加载
                  editorStore.reloadEntityInstances();

                  // 更新编辑器中的标记
                  editor.selection.select(selectedNode);
                  editor.selection.setContent(
                    `<span class="entity" data-entity-id="${entity.id}" data-instance-id="${instanceId}" data-checked="true" style="background-color: ${backgroundColor}">${originalContent}</span>`
                  );
                } else {
                  console.error('实体实例创建失败:', response.data.message);
                  ElMessage.warning('创建实体实例失败，但已在编辑器中标注');

                  // 仍然在编辑器中更新标记
                  editor.selection.select(selectedNode);
                  editor.selection.setContent(
                    `<span class="entity" data-entity-id="${entity.id}" data-checked="true" style="background-color: ${backgroundColor}">${originalContent}</span>`
                  );
                }
              })
              .catch(error => {
                console.error('创建实体实例请求失败:', error);
                ElMessage.error('保存实体实例失败，请检查网络连接');

                // 仍然在编辑器中更新标记
                editor.selection.select(selectedNode);
                editor.selection.setContent(
                  `<span class="entity" data-entity-id="${entity.id}" data-checked="true" style="background-color: ${backgroundColor}">${originalContent}</span>`
                );
              });
          }
        } else {
          // 如果是普通文本，直接添加标注
          const selectedContent = editor.selection.getContent();
          if (selectedContent) {
            // 获取实体颜色，确保一致性
            const backgroundColor = editorStore.getEntityColor(entity.id);

            // 检查是否已经是实体标签
            if (selectedNode.tagName === 'SPAN' && selectedNode.classList.contains('entity')) {
              // 如果已经是实体标签，只更新属性
              // 记录原始实体ID以便调试
              console.log('更新实体ID，从', selectedNode.getAttribute('data-entity-id'), '到', entity.id);
              selectedNode.setAttribute('data-entity-id', entity.id);
              selectedNode.setAttribute('data-checked', 'true');
              selectedNode.style.backgroundColor = backgroundColor;

              // 获取文档ID
              const documentId = editorStore.documentInfo?.id;
              if (!documentId) {
                console.error('未找到文档ID，无法保存实体实例');
                return;
              }

              // 获取或创建实例ID
              const instanceId = selectedNode.getAttribute('data-instance-id') || `${entity.id}_${Date.now()}`;
              selectedNode.setAttribute('data-instance-id', instanceId);

              // 创建实体实例数据
              const instanceData = {
                id: instanceId,
                text: selectedContent,
                documentId: documentId,
                entityId: entity.id,
                isChecked: true
              };

              // 保存到数据库
              createEntityInstance(instanceData)
                .then(response => {
                  if (response.data.code === 200) {
                    console.log('实体实例创建/更新成功:', response.data);
                    // 添加到编辑器的状态
                    editorStore.addEntityInstance(instanceData);

                    // 标记实体实例已更新
                    if (editorStore.markEntityInstancesUpdated) {
                      editorStore.markEntityInstancesUpdated();
                    }
                  } else {
                    console.error('实体实例创建/更新失败:', response.data.message);
                    ElMessage.warning('实体实例保存失败，但已在编辑器中标注');
                  }
                })
                .catch(error => {
                  console.error('创建/更新实体实例请求失败:', error);
                  ElMessage.error('保存实体实例失败，请检查网络连接');
                });
            } else {
              // 如果不是实体标签，添加实体标签
              // 获取文档ID
              const documentId = editorStore.documentInfo?.id;
              if (!documentId) {
                console.error('未找到文档ID，无法保存实体实例');
                editor.selection.setContent(`<span class="entity" data-entity-id="${entity.id}" data-checked="true" style="background-color: ${backgroundColor}">${selectedContent}</span>`);
                return;
              }

              // 创建实例ID
              const instanceId = `${entity.id}_${Date.now()}`;

              // 创建实体实例数据
              const instanceData = {
                id: instanceId,
                text: selectedContent,
                documentId: documentId,
                entityId: entity.id,
                isChecked: true
              };

              // 保存到数据库
              createEntityInstance(instanceData)
                .then(response => {
                  if (response.data.code === 200) {
                    console.log('实体实例创建成功:', response.data);
                    // 添加到编辑器的状态
                    editorStore.addEntityInstance(instanceData);

                    // 标记实体实例已更新
                    if (editorStore.markEntityInstancesUpdated) {
                      editorStore.markEntityInstancesUpdated();
                    }

                    // 更新编辑器中的标记，包含实例ID
                    editor.selection.setContent(`<span class="entity" data-entity-id="${entity.id}" data-instance-id="${instanceId}" data-checked="true" style="background-color: ${backgroundColor}">${selectedContent}</span>`);
                  } else {
                    console.error('实体实例创建失败:', response.data.message);
                    ElMessage.warning('实体实例保存失败，但已在编辑器中标注');

                    // 仍然在编辑器中更新标记，但不包含实例ID
                    editor.selection.setContent(`<span class="entity" data-entity-id="${entity.id}" data-checked="true" style="background-color: ${backgroundColor}">${selectedContent}</span>`);
                  }
                })
                .catch(error => {
                  console.error('创建实体实例请求失败:', error);
                  ElMessage.error('保存实体实例失败，请检查网络连接');

                  // 仍然在编辑器中更新标记，但不包含实例ID
                  editor.selection.setContent(`<span class="entity" data-entity-id="${entity.id}" data-checked="true" style="background-color: ${backgroundColor}">${selectedContent}</span>`);
                });
            }
            // 立即更新实体标记数量和标注文本
            setTimeout(() => debouncedUpdateEntityMarkings(editor), 0);
            // 隐藏弹出框
            entityPopup.style.display = 'none';
          }
        }
      });

      entityPopup.appendChild(button);
    });
  };

  // 隐藏弹出框
  const hideEntityPopup = () => {
    if (entityPopup) {
      entityPopup.style.display = 'none';
    }
  };

  // 初始化弹出框
  editor.on('init', () => {
    initEntityPopup();

    // 监听选择变化事件
    editor.on('SelectionChange', function (e) {
      // 如果有选中内容，显示弹出框
      const selectedContent = editor.selection.getContent();
      if (selectedContent) {
        // 获取选中区域的位置
        const selection = editor.selection.getSel();
        if (selection.rangeCount > 0) {
          const range = selection.getRangeAt(0);
          const rect = range.getBoundingClientRect();
          // 计算弹出框位置（在选中文本的左下方）
          const x = rect.left + window.scrollX + 200;
          const y = rect.bottom + window.scrollY + 120;
          // 显示弹出框
          showEntityPopup(x, y);
        }
      } else {
        // 没有选中内容，隐藏弹出框
        hideEntityPopup();
      }
    });

    // 添加mouseup事件监听器，确保在鼠标释放后保持弹出框显示
    editor.getBody().addEventListener('mouseup', function (e) {
      // 延迟执行，确保在SelectionChange事件之后处理
      setTimeout(() => {
        const selectedContent = editor.selection.getContent();
        if (selectedContent) {
          // 获取选中区域的位置
          const selection = editor.selection.getSel();
          if (selection.rangeCount > 0) {
            const range = selection.getRangeAt(0);
            const rect = range.getBoundingClientRect();
            // 计算弹出框位置（在选中文本的左下方）
            const x = rect.left + window.scrollX + 200;
            const y = rect.bottom + window.scrollY + 120;
            // 显示弹出框
            showEntityPopup(x, y);
          }
        }
      }, 10); // 短暂延迟，确保在SelectionChange之后执行
    });

    // 点击编辑器其他区域时隐藏弹出框
    editor.getDoc().addEventListener('click', (e) => {
      // 检查是否点击了弹出框内部
      if (entityPopup && !entityPopup.contains(e.target)) {
        hideEntityPopup();
      }
    });
  });

  // 监听选择变化事件，用于更新实体按钮
  editor.on('SelectionChange', function (e) {
    // 这里可以添加额外的逻辑，如果需要的话
  })
  // 添加更多操作按钮
  editor.ui.registry.addMenuButton('moreOptions', {
    icon: 'more-drawer',
    tooltip: '更多操作',
    fetch: (callback) => {
      const entities = window.entities || [];
      const items = entities.map(entity => ({
        type: 'menuitem',
        text: `${entity.text}`,
        onAction: () => {
          const selectedContent = editor.selection.getContent();
          if (selectedContent) {
            // 获取文档ID
            const documentId = editorStore.documentInfo?.id;
            if (!documentId) {
              console.error('未找到文档ID，无法保存实体实例');
              return;
            }

            // 获取实体颜色，确保一致性
            const backgroundColor = editorStore.getEntityColor(entity.id);

            // 检查是否已经是实体标签
            const selectedNode = editor.selection.getNode();
            if (selectedNode.tagName === 'SPAN' && selectedNode.classList.contains('entity')) {
              // 如果已经是实体标签，只更新属性
              // 记录原始实体ID以便调试
              console.log('更新实体ID，从', selectedNode.getAttribute('data-entity-id'), '到', entity.id);
              selectedNode.setAttribute('data-entity-id', entity.id);
              selectedNode.setAttribute('data-checked', 'true');
              selectedNode.style.backgroundColor = backgroundColor;

              // 获取或创建实例ID
              const instanceId = selectedNode.getAttribute('data-instance-id') || `${entity.id}_${Date.now()}`;
              selectedNode.setAttribute('data-instance-id', instanceId);

              // 创建实体实例数据
              const instanceData = {
                id: instanceId,
                text: selectedContent,
                documentId: documentId,
                entityId: entity.id,
                isChecked: true
              };

              // 保存到数据库
              createEntityInstance(instanceData)
                .then(response => {
                  if (response.data.code === 200) {
                    console.log('实体实例创建/更新成功:', response.data);
                    // 添加到编辑器的状态
                    editorStore.addEntityInstance(instanceData);

                    // 标记实体实例已更新
                    if (editorStore.markEntityInstancesUpdated) {
                      editorStore.markEntityInstancesUpdated();
                    }
                  } else {
                    console.error('实体实例创建/更新失败:', response.data.message);
                    ElMessage.warning('实体实例保存失败，但已在编辑器中标注');
                  }
                })
                .catch(error => {
                  console.error('创建/更新实体实例请求失败:', error);
                  ElMessage.error('保存实体实例失败，请检查网络连接');
                });
            } else {
              // 如果不是实体标签，添加实体标签
              // 创建实例ID
              const instanceId = `${entity.id}_${Date.now()}`;

              // 创建实体实例数据
              const instanceData = {
                id: instanceId,
                text: selectedContent,
                documentId: documentId,
                entityId: entity.id,
                isChecked: true
              };

              // 保存到数据库
              createEntityInstance(instanceData)
                .then(response => {
                  if (response.data.code === 200) {
                    console.log('实体实例创建成功:', response.data);
                    // 添加到编辑器的状态
                    editorStore.addEntityInstance(instanceData);

                    // 标记实体实例已更新
                    if (editorStore.markEntityInstancesUpdated) {
                      editorStore.markEntityInstancesUpdated();
                    }

                    // 更新编辑器中的标记，包含实例ID
                    editor.selection.setContent(`<span class="entity" data-entity-id="${entity.id}" data-instance-id="${instanceId}" data-checked="true" style="background-color: ${backgroundColor}">${selectedContent}</span>`);
                  } else {
                    console.error('实体实例创建失败:', response.data.message);
                    ElMessage.warning('实体实例保存失败，但已在编辑器中标注');

                    // 仍然在编辑器中更新标记，但不包含实例ID
                    editor.selection.setContent(`<span class="entity" data-entity-id="${entity.id}" data-checked="true" style="background-color: ${backgroundColor}">${selectedContent}</span>`);
                  }
                })
                .catch(error => {
                  console.error('创建实体实例请求失败:', error);
                  ElMessage.error('保存实体实例失败，请检查网络连接');

                  // 仍然在编辑器中更新标记，但不包含实例ID
                  editor.selection.setContent(`<span class="entity" data-entity-id="${entity.id}" data-checked="true" style="background-color: ${backgroundColor}">${selectedContent}</span>`);
                });
            }

            // 立即更新实体标记数量和标注文本
            setTimeout(() => debouncedUpdateEntityMarkings(editor), 0);
          }
        }
      }));
      callback(items);
    }
  });
  // 添加匹配标注实体按钮
  editor.ui.registry.addButton('matchEntity', {
    icon: 'zoom-in',
    tooltip: '匹配标注',
    onAction: () => {
      dialogVisible.value = true // 显示匹配标注对话框
    }
  })

  // 添加批量匹配标注实体按钮
  editor.ui.registry.addButton('batchMatchEntity', {
    icon: 'quote',
    tooltip: '批量匹配标注实体',
    onAction: () => {
      batchDialogVisible.value = true // 显示批量匹配标注对话框
    }
  })

  // 添加自动标注实体按钮
  editor.ui.registry.addButton('autoAnnotateEntity', {
    icon: 'toc',
    tooltip: '自动标注实体',
    onAction: () => {
      autoAnnotateVisible.value = true // 显示自动标注对话框
    }
  })

  // 添加自定义上下文菜单
  editor.ui.registry.addContextMenu('entityContextMenu', {
    update: (element) => {
      // 检查是否点击了实体标注元素
      const isEntitySpan = element.tagName === 'SPAN' && element.classList.contains('entity');
      if (!isEntitySpan) {
        return [];
      }

      // 获取当前实体ID
      const entityId = element.getAttribute('data-entity-id');

      // 获取实体列表
      const entities = window.entities || [];
      // 查找当前实体
      const currentEntity = entities.find(e => e.id === entityId);

      if (!currentEntity) {
        return [];
      }

      // 构建上下文菜单项
      // 获取当前检查状态
      const isChecked = element.getAttribute('data-checked') !== 'false';

      return [
        {
          type: 'item',
          text: isChecked ? `设定实体状态为"未检查"` : `设定实体状态为"已检查"`,
          icon: isChecked ? 'warning' : 'checkmark',
          onAction: () => {
            // 切换检查状态
            const newState = isChecked ? 'false' : 'true';
            element.setAttribute('data-checked', newState);

            // 获取实体实例ID
            const instanceId = element.getAttribute('data-instance-id');
            // 获取文档ID
            const documentId = editorStore.documentInfo?.id;

            if (instanceId && documentId) {
              // 调用API更新数据库中的实体实例
              updateEntityInstance(instanceId, documentId, !isChecked)
                .then(response => {
                  if (response.data.code === 200) {
                    console.log(`实体实例状态已更新为: ${!isChecked ? '已检查' : '未检查'}`);
                    // 更新界面提示
                    ElMessage.success(`已将实体状态设为${!isChecked ? '已检查' : '未检查'}`);
                    // 通知editorStore更新实体实例数据
                    if (editorStore.markEntityInstancesUpdated) {
                      editorStore.markEntityInstancesUpdated();
                    }
                  } else {
                    console.error('更新实体实例状态失败:', response.data.message);
                    ElMessage.error('更新实体状态失败');
                  }
                })
                .catch(error => {
                  console.error('更新实体实例API请求失败:', error);
                  ElMessage.error('更新实体状态失败：网络错误');
                });
            }

            // 更新实体标记数量和标注文本
            setTimeout(() => debouncedUpdateEntityMarkings(editor), 0);
          }
        },
        {
          type: 'item',
          text: `设定全部相同实体均为"未检查"`,
          icon: 'warning',
          onAction: () => {
            // 获取所有相同ID的实体元素
            const allEntitySpans = editor.getBody().querySelectorAll(`span.entity[data-entity-id="${entityId}"]`);
            allEntitySpans.forEach(span => {
              span.setAttribute('data-checked', 'false');
            });

            // 获取文档ID
            const documentId = editorStore.documentInfo?.id;
            if (!documentId) {
              console.error('未找到文档ID，无法更新实体实例');
              return;
            }

            // 调用API更新数据库中的实体实例
            updateEntityInstancesByEntityId(documentId, entityId, false)
              .then(response => {
                if (response.data.code === 200) {
                  console.log('所有相同实体实例状态已更新为未检查');
                  // 通知editorStore更新实体实例数据
                  if (editorStore.markEntityInstancesUpdated) {
                    editorStore.markEntityInstancesUpdated();
                  }
                } else {
                  console.error('更新实体实例状态失败:', response.data.message);
                }
              })
              .catch(error => {
                console.error('更新实体实例API请求失败:', error);
              });

            // 更新实体标记数量和标注文本
            setTimeout(() => debouncedUpdateEntityMarkings(editor), 0);
          }
        },
        {
          type: 'item',
          text: `取消标注该实体`,
          icon: 'remove',
          onAction: () => {
            // 获取文档ID
            const documentId = editorStore.documentInfo?.id;
            // 获取原始内容
            const originalContent = element.textContent;
            console.log('[实体标注] 取消标注该实体，获取原始内容:', originalContent);

            // 如果有文档ID，尝试从数据库删除实体实例
            if (documentId) {
              // 获取实例ID，优先使用data-instance-id属性
              const instanceId = element.getAttribute('data-instance-id');
              const entityId = element.getAttribute('data-entity-id');

              if (instanceId) {
                // 直接使用实例ID删除
                deleteEntityInstance(documentId, instanceId)
                  .then(response => {
                    if (response.data.code === 200) {
                      console.log('成功从数据库删除实体实例, instanceId:', instanceId);
                      // 从editorStore中删除实体实例
                      editorStore.deleteEntityInstance(instanceId);
                      // 强制标记实体实例数据已更新
                      editorStore.markEntityInstancesUpdated();
                    } else {
                      console.warn('从数据库删除实体实例失败:', response.data.message);
                    }
                  })
                  .catch(error => {
                    console.error('删除实体实例请求失败:', error);
                  });
              } else if (entityId) {
                // 如果没有实例ID但有实体ID，尝试通过文本内容和实体ID查找
                const entityInstances = editorStore.getEntityInstances;
                const instanceToDelete = entityInstances.find(instance =>
                  instance.entityId === entityId && instance.text === originalContent
                );

                if (instanceToDelete) {
                  deleteEntityInstance(documentId, instanceToDelete.id)
                    .then(response => {
                      if (response.data.code === 200) {
                        console.log('成功从数据库删除实体实例, 通过文本匹配');
                        // 从editorStore中删除实体实例
                        editorStore.deleteEntityInstance(instanceToDelete.id);
                        // 强制标记实体实例数据已更新
                        editorStore.markEntityInstancesUpdated();
                      } else {
                        console.warn('从数据库删除实体实例失败:', response.data.message);
                      }
                    })
                    .catch(error => {
                      console.error('删除实体实例请求失败:', error);
                    });
                }
              }
            }

            // 选中该元素
            editor.selection.select(element);
            // 替换为普通文本
            editor.selection.setContent(originalContent);

            // 重置编辑器内容哈希值，强制下次更新
            editor._lastMarkingsHash = null;

            // 立即更新实体标记数量和标注文本，使用非防抖版本确保立即执行
            setTimeout(() => updateEntityMarkings(editor), 0);
          }
        },
        {
          type: 'item',
          text: `取消标注全部相同实体`,
          icon: 'remove',
          onAction: () => {
            // 获取文档ID
            const documentId = editorStore.documentInfo?.id;
            const entityId = element.getAttribute('data-entity-id');

            // 先处理DOM中的所有实体标签，确保内容更新
            // 获取所有相同ID的实体元素
            const allEntitySpans = Array.from(
              editor.getBody().querySelectorAll(`span.entity[data-entity-id="${entityId}"]`)
            );

            // 记录实体数量用于调试
            console.log(`[实体标注] 找到 ${allEntitySpans.length} 个实体标签需要取消标注`);

            // 从后向前处理，避免DOM结构变化影响选择
            for (let i = allEntitySpans.length - 1; i >= 0; i--) {
              const span = allEntitySpans[i];
              const originalContent = span.textContent;
              editor.selection.select(span);
              editor.selection.setContent(originalContent);
            }

            // 重置编辑器内容哈希值，强制下次更新
            editor._lastMarkingsHash = null;

            // 如果有文档ID，尝试从数据库批量删除实体实例
            if (documentId && entityId) {
              // 向后端发送请求删除数据库中的实体实例
              deleteEntityInstancesByEntityId(documentId, entityId)
                .then(response => {
                  if (response.data.code === 200) {
                    console.log('成功从数据库批量删除实体实例');
                    // 从editorStore中批量删除该实体类的所有实例
                    editorStore.deleteEntityInstancesByEntityId(entityId);
                    // 强制标记实体实例数据已更新
                    editorStore.markEntityInstancesUpdated();

                    // 手动触发直接调用更新方法，不使用防抖
                    setTimeout(() => {
                      console.log('[实体标注] 手动触发实体标记计数更新');
                      if (typeof window.updateEntityMarkedCount === 'function') {
                        // 调用全局更新函数，传入空数据重置计数
                        const resetData = {};
                        resetData[entityId] = 0;
                        window.updateEntityMarkedCount(resetData);
                      }
                    }, 50);
                  } else {
                    console.warn('从数据库批量删除实体实例失败:', response.data.message);
                  }
                })
                .catch(error => {
                  console.error('批量删除实体实例请求失败:', error);
                });
            }

            // 立即更新实体标记数量和标注文本，使用非防抖版本确保立即执行
            setTimeout(() => updateEntityMarkings(editor), 0);
          }
        }
      ];
    }
  });
}

// 组件卸载前清理关系线
onBeforeUnmount(() => {
  console.log('[实体标注] 组件卸载，开始清理资源');

  // 确保最后一次保存到后端
  if (form.content) {
    debouncedSaveContent.flush(); // 立即执行保存而不是等待
  }

  // 清除关系线
  clearRelationLines();

  // 清除所有箭头指示器
  editorStore.clearAllArrowIndicators();

  // 清理实体实例数据
  editorStore.setEntityInstances([]);

  // 清理编辑器实例
  const editorInstance = window.tinymce?.get('editor');
  if (editorInstance) {
    // 清理MutationObserver
    try {
      if (editorInstance.dataCheckedObserver) {
        console.log('[实体标注] 清理属性变化监听器');
        editorInstance.dataCheckedObserver.disconnect();
        editorInstance.dataCheckedObserver = null;
      }
    } catch (error) {
      console.error('[实体标注] 清理属性变化监听器时出错:', error);
    }

    // 移除编辑器实例
    try {
      editorInstance.remove();
      console.log('[实体标注] 已移除编辑器实例');
    } catch (error) {
      console.error('[实体标注] 移除编辑器实例时出错:', error);
    }
  }

  // 清理所有定时器
  if (timerInterval) {
    clearInterval(timerInterval);
    timerInterval = null;
    console.log('[实体标注] 已清理主定时器');
  }

  // 清理颜色同步定时器
  if (colorSyncInterval) {
    clearInterval(colorSyncInterval);
    colorSyncInterval = null;
    console.log('[实体标注] 已清理颜色同步定时器');
  }

  // 清理关系绘制定时器
  if (window.drawRelationsTimeout) {
    clearTimeout(window.drawRelationsTimeout);
    window.drawRelationsTimeout = null;
    console.log('[实体标注] 已清理关系绘制定时器');
  }

  // 重置编辑器标注模式
  editorStore.setAnnotationMode('');

  console.log('[实体标注] 组件资源清理完成');
});

// 存储已创建的关系线元素，用于后续清理
const relationLines = ref([]);

// 清除所有关系线
const clearRelationLines = () => {
  // 移除所有关系线
  relationLines.value.forEach(line => {
    if (line.leaderLine) {
      try {
        const lineElement = line.leaderLine.element;
        if (lineElement && lineElement.parentNode) {
          line.leaderLine.remove();
        }
      } catch (error) {
        console.warn('移除关系线时出错:', error);
      }
    }
  });
  relationLines.value = [];
};

// 修改drawAllRelations函数，使用window.LeaderLine而不是直接使用LeaderLine
const drawAllRelations = () => {
  // 确保编辑器实例存在
  const editor = window.tinymce?.get('editor');
  if (!editor || !editor.getBody) {
    console.warn('[实体标注] 编辑器实例不存在或未完全初始化，无法绘制关系箭头');
    return;
  }

  // 确保 LeaderLine 库已加载
  if (typeof window.LeaderLine === 'undefined') {
    console.warn('[实体标注] LeaderLine库未加载，无法绘制关系箭头');
    return;
  }

  const editorBody = editor.getBody();
  if (!editorBody) {
    console.warn('[实体标注] 无法获取编辑器正文元素，无法绘制关系箭头');
    return;
  }

  // 尝试从localStorage获取关系线信息
  let relationLinesInfo = [];
  try {
    const relationLinesInfoStr = localStorage.getItem('relationLinesInfo');
    if (relationLinesInfoStr) {
      relationLinesInfo = JSON.parse(relationLinesInfoStr);
      console.log('[实体标注] 从localStorage获取的关系线信息:', relationLinesInfo.length);
    }
  } catch (error) {
    console.error('[实体标注] 解析关系线信息时出错:', error);
    return; // 如果解析出错，直接返回
  }

  // 如果有关系线信息，优先使用它来绘制关系线
  if (relationLinesInfo && relationLinesInfo.length > 0) {
    // 用于跟踪已绘制的关系，防止重复
    const drawnRelations = new Set();

    // 遍历所有关系线信息
    relationLinesInfo.forEach((lineInfo, index) => {
      try {
        if (!lineInfo || !lineInfo.sourceId || !lineInfo.targetId || !lineInfo.relationId) {
          console.warn(`[实体标注] 关系线信息 ${index} 不完整，跳过`);
          return;
        }

        const sourceId = lineInfo.sourceId;
        const targetId = lineInfo.targetId;
        const relationId = lineInfo.relationId;

        // 创建关系的唯一标识符
        const relationKey = `${sourceId}-${targetId}-${relationId}`;

        // 如果已经绘制过这个完全相同的关系，则跳过
        if (drawnRelations.has(relationKey)) {
          return;
        }

        // 查找源实体和目标实体元素
        const sourceElement = editorBody.querySelector(`span[data-entity-id="${sourceId}"]`);
        const targetElement = editorBody.querySelector(`span[data-entity-id="${targetId}"]`);

        if (!sourceElement || !targetElement) {
          console.warn(`[实体标注] 未找到关系 ${index} 的源实体或目标实体`);
          return;
        }

        // 获取关系类的样式
        const relations = window.relations || [];
        const relationClass = relations.find(r => r.id === relationId);
        const color = lineInfo.color || relationClass?.style?.['background-color'] || '#1890ff';

        // 使用 try-catch 包装 LeaderLine 创建
        try {
          // 创建 LeaderLine 实例 - 使用 window.LeaderLine
          const line = new window.LeaderLine(
            sourceElement,
            targetElement,
            {
              color: color,
              size: 2.5,
              startSocket: lineInfo.startSocket || 'top',
              endSocket: lineInfo.endSocket || 'bottom',
              path: 'fluid',
              startSocketGravity: 50,
              endSocketGravity: 50,
              startPlug: 'behind',
              endPlug: 'arrow3',
              endPlugSize: 1.5,
              startPlugColor: color,
              endPlugColor: color,
              animOptions: { duration: 300, timing: 'linear' }
            }
          );

          // 添加关系文本标签
          if (lineInfo.relationText) {
            try {
              line.setOptions({
                middleLabel: window.LeaderLine.captionLabel(lineInfo.relationText, {
                  color: color,
                  fontWeight: 'bold',
                  fontSize: '12px',
                  fontFamily: 'Arial, sans-serif',
                  padding: [4, 8, 4, 8],
                  backgroundColor: 'white',
                  borderRadius: 3,
                  borderWidth: 1.5,
                  borderColor: color
                })
              });

              // 如果是引用关系，设置虚线样式
              if (lineInfo.relationText === '引用' || lineInfo.dash) {
                line.setOptions({
                  dash: lineInfo.dash || { len: 5, gap: 3 }
                });
              }
            } catch (labelError) {
              console.error('[实体标注] 设置关系标签时出错:', labelError);
            }
          }

          // 保存关系线信息
          relationLines.value.push({
            id: lineInfo.id || `relation-${sourceId}-${targetId}-${relationId}-${Date.now()}`,
            sourceId: sourceId,
            targetId: targetId,
            relationId: relationId,
            relationText: lineInfo.relationText,
            leaderLine: line
          });

          // 添加标记，确保LeaderLine元素不会被保存
          setTimeout(() => {
            try {
              // 查找并标记所有LeaderLine相关元素
              const leaderLineElements = document.querySelectorAll('div.leader-line, div.leader-line-label-wrapper, div.leader-line-caption, div.leader-line-line, div.leader-line-plug, div.leader-line-marker');
              leaderLineElements.forEach(element => {
                // 添加属性，使TinyMCE忽略这些元素
                element.setAttribute('data-mce-bogus', 'all');
                // 额外添加一个自定义属性，便于后续清理
                element.setAttribute('data-leader-line-element', 'true');
                // 添加特定样式，使其在视觉上与内容分离
                element.style.pointerEvents = 'none'; // 防止用户交互
              });
            } catch (error) {
              console.warn('[实体标注] 标记LeaderLine元素时出错:', error);
            }
          }, 200);

          // 标记为已绘制
          drawnRelations.add(relationKey);
        } catch (lineError) {
          console.error(`[实体标注] 创建关系线 ${index} 时出错:`, lineError);
        }
      } catch (error) {
        console.error(`[实体标注] 处理关系线信息 ${index} 时出错:`, error);
      }
    });

    console.log(`[实体标注] 已从关系线信息绘制 ${drawnRelations.size} 个关系箭头`);
    return;
  }

  // 如果没有关系线信息，则从relationsData绘制
  // 从localStorage获取关系数据
  const relationsData = JSON.parse(localStorage.getItem('relationsData') || '[]');
  if (relationsData.length === 0) {
    console.log('未找到任何关系数据');
    return;
  }

  // 确保window.relations已加载
  if (!window.relations) {
    // 尝试从localStorage加载关系类定义
    try {
      const storedRelations = localStorage.getItem('relations');
      if (storedRelations) {
        window.relations = JSON.parse(storedRelations);
        console.log('从localStorage加载关系类定义:', window.relations.length);
      } else {
        console.warn('未找到关系类定义，箭头将使用默认颜色');
        window.relations = [];
      }
    } catch (error) {
      console.error('加载关系类定义时出错:', error);
      window.relations = [];
    }
  }

  // 用于跟踪已绘制的关系，防止重复
  const drawnRelations = new Set();

  // 遍历所有关系数据
  relationsData.forEach((relationData, index) => {
    const sourceId = relationData.sourceEntity.id;
    const targetId = relationData.targetEntity.id;
    const relationId = relationData.relation.id;
    const relationText = relationData.relation.text || '';

    // 创建关系的唯一标识符
    const relationKey = `${sourceId}-${targetId}-${relationId}`;

    // 如果已经绘制过这个完全相同的关系，则跳过
    if (drawnRelations.has(relationKey)) {
      console.log(`跳过重复的关系 ${index + 1}:`, sourceId, '->', targetId, relationId);
      return;
    }

    // 查找源实体和目标实体元素
    const sourceElement = editorBody.querySelector(`span[data-entity-id="${sourceId}"]`);
    const targetElement = editorBody.querySelector(`span[data-entity-id="${targetId}"]`);

    if (sourceElement && targetElement) {
      console.log(`找到源实体和目标实体，绘制关系线:`, sourceId, '->', targetId, relationText);

      // 创建一个唯一的ID用于关系线
      const lineId = `relation-${sourceId}-${targetId}-${relationId}-${Date.now()}`;

      // 获取关系类的样式
      const relations = window.relations || [];
      const relationClass = relations.find(r => r.id === relationId);
      const color = relationClass?.style?.['background-color'] || '#1890ff';

      // 确定最佳连接点
      let startSocket = 'top';
      let endSocket = 'bottom';
      const path = 'fluid';

      // 根据元素位置确定最佳连接点
      const sourceRect = sourceElement.getBoundingClientRect();
      const targetRect = targetElement.getBoundingClientRect();

      if (targetRect.top + targetRect.height < sourceRect.top) {
        startSocket = 'top';
        endSocket = 'bottom';
      } else if (targetRect.top > sourceRect.top + sourceRect.height) {
        startSocket = 'bottom';
        endSocket = 'top';
      } else if (targetRect.left + targetRect.width < sourceRect.left) {
        startSocket = 'left';
        endSocket = 'right';
      } else {
        startSocket = 'right';
        endSocket = 'left';
      }

      // 创建LeaderLine实例 - 使用window.LeaderLine
      const line = new window.LeaderLine(
        sourceElement,
        targetElement,
        {
          color: color,
          size: 2.5,
          startSocket: startSocket,
          endSocket: endSocket,
          path: path,
          startSocketGravity: 50,
          endSocketGravity: 50,
          startPlug: 'behind',
          endPlug: 'arrow3',
          endPlugSize: 1.5,
          startPlugColor: color,
          endPlugColor: color,
          animOptions: { duration: 300, timing: 'linear' }
        }
      );

      // 添加关系文本标签
      if (relationText) {
        line.setOptions({
          middleLabel: window.LeaderLine.captionLabel(relationText, {
            color: color,
            fontWeight: 'bold',
            fontSize: '12px',
            fontFamily: 'Arial, sans-serif',
            padding: [4, 8, 4, 8],
            backgroundColor: 'white',
            borderRadius: 3,
            borderWidth: 1.5,
            borderColor: color
          })
        });

        if (relationText === '引用') {
          line.setOptions({
            dash: { len: 5, gap: 3 }
          });
        }
      }

      // 保存关系线信息
      relationLines.value.push({
        id: lineId,
        sourceId: sourceId,
        targetId: targetId,
        relationId: relationId,
        relationText: relationText,
        leaderLine: line
      });

      // 添加标记，确保LeaderLine元素不会被保存
      setTimeout(() => {
        try {
          // 查找并标记所有LeaderLine相关元素
          const leaderLineElements = document.querySelectorAll('div.leader-line, div.leader-line-label-wrapper, div.leader-line-caption, div.leader-line-line, div.leader-line-plug, div.leader-line-marker');
          leaderLineElements.forEach(element => {
            // 添加属性，使TinyMCE忽略这些元素
            element.setAttribute('data-mce-bogus', 'all');
            // 额外添加一个自定义属性，便于后续清理
            element.setAttribute('data-leader-line-element', 'true');
            // 添加特定样式，使其在视觉上与内容分离
            element.style.pointerEvents = 'none'; // 防止用户交互
          });
        } catch (error) {
          console.warn('[实体标注] 标记LeaderLine元素时出错:', error);
        }
      }, 200);

      // 标记为已绘制
      drawnRelations.add(relationKey);
    } else {
      console.warn(`未找到关系 ${index + 1} 的源实体或目标实体:`,
        sourceElement ? '源实体存在' : '源实体不存在',
        targetElement ? '目标实体存在' : '目标实体不存在');
    }
  });

  console.log(`已绘制 ${drawnRelations.size} 个关系箭头`);
};

// 监听编辑器内容变化，保存到后端
watch(() => form.content, (newContent) => {
  if (newContent) {
    debouncedSaveContent(newContent);
  }
})

// 在onMounted钩子中整合加载实体实例数据的逻辑
onMounted(() => {
  console.log('[实体标注] 组件已挂载');

  // 设置编辑器标注模式
  editorStore.setAnnotationMode('entity');

  // 加载实体实例数据函数
  const loadEntityInstances = () => {
    // 获取文档ID
    const documentId = editorStore.documentInfo?.id;
    if (!documentId) {
      console.warn('未找到文档ID，无法加载实体实例数据');
      return;
    }

    // 显示加载提示
    const loadingInstance = ElLoading.service({
      fullscreen: true,
      text: '正在加载实体实例数据...'
    });

    // 发送请求获取实体实例数据
    getEntityInstances(documentId)
      .then(response => {
        loadingInstance.close();
        if (response.data.code === 200 && response.data.data) {
          const instancesData = response.data.data;
          console.log('从数据库加载了实体实例数据:', instancesData);

          // 确保instancesData是数组，如果不是则进行转换或创建空数组
          const instances =
            Array.isArray(instancesData) ? instancesData : (instancesData.instances && Array.isArray(instancesData.instances)) ? instancesData.instances : [];

          if (instances.length === 0) {
            console.log('没有找到实体实例数据或数据格式不正确');
            editorStore.setEntityInstances([]);
            return;
          }

          // 确保每个实例使用与其对应实体类一致的颜色
          const processedInstances = instances.map(instance => {
            // 通过entityId获取对应实体类的颜色
            const backgroundColor = editorStore.getEntityColor(instance.entityId);
            return {
              ...instance,
              style: { 'background-color': backgroundColor }
            };
          });

          // 更新editorStore中的实体实例数据
          editorStore.setEntityInstances(processedInstances);

          // 获取编辑器实例
          const editor = window.tinymce.get('editor');
          if (editor) {
            // 在这里我们不需要修改编辑器内容，因为内容中已经包含了实体标注
            // 只需要确保更新实体计数和显示
            setTimeout(() => {
              throttledUpdateEntityMarkings(editor);
            }, 500);
          }
        } else {
          console.warn('加载实体实例数据失败:', response.data.message);
        }
      })
      .catch(error => {
        loadingInstance.close();
        console.error('请求实体实例数据失败:', error);
        ElMessage.error('加载实体实例数据失败，请检查网络连接');
      });
  };

  // 设置定期同步颜色的定时器
  colorSyncInterval = setInterval(() => {
    try {
      const editor = window.tinymce?.get('editor');
      if (editor) {
        // 定期检查和同步颜色
        synchronizeEntityColors(editor);
      }
    } catch (error) {
      console.error('[实体标注] 定期同步实体颜色时出错:', error);
    }
  }, 30000); // 每30秒同步一次

  // 加载第三方库并初始化编辑器
  loadLeaderLine()
    .then(() => {
      console.log('[实体标注] LeaderLine库已加载，开始加载TinyMCE');
      return loadTinyMCE();
    })
    .then(() => {
      console.log('[实体标注] TinyMCE已加载，开始初始化编辑器');
      // 富文本编辑器
      nextTick(() => {
        const editorConfig = {
          selector: '#editor', // 选择器，指定哪个元素使用 TinyMCE
          skin_url: '/tinymce/skins/ui/oxide',
          content_css: '/tinymce/tinymce.css',
          license_key: 'gpl', // 许可密钥，如果是 GPL 版本则不需要设置
          language: 'zh_CN', // 语言设置
          width: '100%', // 编辑器宽度
          height: 500, // 编辑器高度
          menubar: false, // 是否显示菜单栏
          statusbar: true, // 是否显示状态栏
          branding: false, // 去除底部的 TinyMCE 广告
          toolbar: 'matchEntity batchMatchEntity autoAnnotateEntity moreOptions',
          paste_as_text: true,
          toolbar_sticky: true, // 工具栏固定在顶部
          contextmenu: 'entityContextMenu',
          // 扩展有效元素，确保所有标注类型都能被保留
          extended_valid_elements: 'p[structure-type|class|style],span[data-entity-id|data-checked|data-mce-style|class|style|data-relation-id|data-relation-role|data-relation-target|data-relation-source|data-relation-target-text|data-relation-target-type|var-name]',
          content_style: `
            /* 实体标注样式 */
            .entity {
              background-color: yellow;
              padding: 2px 0;
              border-radius: 2px;
              cursor: pointer;
              position: relative;
            }
            /* 未检查状态的实体，添加小红点指示器 */
            .entity[data-checked="false"]::after {
              content: "";
              position: absolute;
              top: 2px;
              right: 2px;
              width: 6px;
              height: 6px;
              background-color: #ff4d4f;
              border-radius: 50%;
              z-index: 100;
              box-shadow: 0 0 2px rgba(0, 0, 0, 0.3);
            }
            /* 关系标注样式 */
            .relation-source {
              background-color: #ffcccc;
              padding: 2px 0;
              border-radius: 2px;
              cursor: pointer;
            }
            .relation-target {
              background-color: #ccffcc;
              padding: 2px 0;
              border-radius: 2px;
              cursor: pointer;
            }
            /* 结构标注样式 */
            p[structure-type="卷"] {
              background-color: #e6f7ff;
              padding: 10px;
              margin: 10px 0;
              border-left: 3px solid #1890ff;
            }
            p[structure-type="篇"] {
              background-color: #f6ffed;
              padding: 10px;
              margin: 10px 0;
              border-left: 3px solid #52c41a;
            }
            p[structure-type="章"] {
              background-color: #fff7e6;
              padding: 10px;
              margin: 10px 0;
              border-left: 3px solid #faad14;
            }
            p[structure-type="节"] {
              background-color: #fff0f6;
              padding: 10px;
              margin: 10px 0;
              border-left: 3px solid #eb2f96;
            }
            p[structure-type="小节"] {
              background-color: #f9f0ff;
              padding: 10px;
              margin: 10px 0;
              border-left: 3px solid #722ed1;
            }
            p[structure-type="注"] {
              background-color: #f2f6fc;
              padding: 10px;
              margin: 10px 0;
              border-left: 3px solid #1890ff;
            }
            p[structure-type="疏"] {
              background-color: #e6fffb;
              padding: 10px;
              margin: 10px 0;
              border-left: 3px solid #13c2c2;
            }
            p[structure-type="引"] {
              background-color: #fcffe6;
              padding: 10px;
              margin: 10px 0;
              border-left: 3px solid #a0d911;
            }
            p[structure-type="作者"] {
              background-color: #fff2e8;
              padding: 10px;
              margin: 10px 0;
              border-left: 3px solid #fa541c;
            }
            p[structure-type="目录"] {
              background-color: #e6f7ff;
              padding: 10px;
              margin: 10px 0;
              border-left: 3px solid #1890ff;
            }
            /* 关系标注的箭头指示器 */
            .entity-arrow-indicator {
              position: absolute;
              width: 0;
              height: 0;
              border-left: 6px solid transparent;
              border-right: 6px solid transparent;
              border-bottom: 10px solid #ff4d4f;
              cursor: pointer;
              z-index: 999;
            }
          `,
          // 注册自定义按钮和其他功能
          setup: function (editor) {
            setupEditor(editor);
          },
          init_instance_callback: (editor) => {
            // 从editor获取内容
            const editorContent = editorStore.getCurrentContent
            console.log('editorContent:', editorContent);
            editor.setContent(editorContent)
            editor.on('change NodeChange SetContent ObjectResized input keyup blur AttributeChange', () => {
              try {
                // 每次内容变化时清理关系类型文本
                cleanupRelationLabelsInContent(editor);
                form.content = editor.getContent();
                // 将当前的内容保存到editorStore中
                editorStore.setContent(form.content);
                console.log('form.content:', form.content);

                // 保存到后端
                debouncedSaveContent(form.content);

                // 使用防抖函数延迟绘制关系线，避免频繁更新
                clearTimeout(window.drawRelationsTimeout);
                window.drawRelationsTimeout = setTimeout(() => {
                  drawAllRelations();
                }, 300);
              } catch (error) {
                console.error('[实体标注] 处理编辑器内容变化时出错:', error);
              }
            });

            // 添加对DOM元素属性变化的监听
            setTimeout(() => {
              try {
                const editorBody = editor.getBody();
                if (editorBody) {
                  console.log('[实体标注] 初始化属性变化监听器');

                  // 使用MutationObserver监听DOM属性变化
                  const observer = new MutationObserver((mutations) => {
                    let attributeChanged = false;

                    mutations.forEach(mutation => {
                      // 检查是否有data-checked属性变化
                      if (mutation.type === 'attributes' &&
                        mutation.attributeName === 'data-checked' &&
                        mutation.target.nodeName === 'SPAN' &&
                        mutation.target.classList.contains('entity')) {
                        attributeChanged = true;
                        console.log('[实体标注] 检测到data-checked属性变化:', mutation.target);
                      }
                    });

                    // 如果监测到属性变化，触发保存
                    if (attributeChanged) {
                      console.log('[实体标注] 属性变化触发内容保存');
                      form.content = editor.getContent();
                      debouncedSaveContent(form.content);
                    }
                  });

                  // 配置观察器选项
                  observer.observe(editorBody, {
                    attributes: true, // 观察属性变化
                    attributeFilter: ['data-checked'], // 只关注data-checked属性
                    subtree: true, // 观察所有子节点
                    childList: false // 不观察子节点添加或删除
                  });

                  // 存储观察器以便后续清理
                  editor.dataCheckedObserver = observer;
                }
              } catch (error) {
                console.error('[实体标注] 初始化属性变化监听器时出错:', error);
              }
            }, 500);

            // 延迟同步实体颜色，确保编辑器和实体类数据都已加载
            setTimeout(() => {
              try {
                // 同步实体颜色
                synchronizeEntityColors(editor);
              } catch (error) {
                console.error('[实体标注] 初始同步实体颜色时出错:', error);
              }
            }, 1000);

            // 延迟绘制关系箭头，确保编辑器完全初始化
            setTimeout(() => {
              try {
                // 绘制关系箭头
                drawAllRelations();
              } catch (error) {
                console.error('[实体标注] 初始绘制关系箭头时出错:', error);
              }
            }, 500);

            // 加载实体实例数据
            setTimeout(() => {
              loadEntityInstances();
            }, 1000);
          }
        };

        // 保存编辑器配置到状态管理
        editorStore.setEditorConfig(editorConfig);

        // 初始化编辑器
        try {
          window.tinymce.init(editorConfig);
        } catch (error) {
          console.error('[实体标注] 初始化TinyMCE编辑器时出错:', error);
        }
      });
    })
    .catch((error) => {
      console.error('[实体标注] 加载库失败:', error);
    });

  // 修改定时更新逻辑，减少更新频率并添加错误处理
  timerInterval = setInterval(() => {
    try {
      const editor = window.tinymce?.get('editor');
      if (editor) {
        // 绘制所有关系线
        drawAllRelations();
      }
    } catch (error) {
      console.error('[实体标注] 定时更新时出错:', error);
      // 直接清理定时器，不使用cleanup函数
      if (timerInterval) {
        clearInterval(timerInterval);
        timerInterval = null;
      }
    }
  }, 3000); // 增加间隔到3秒，减少更新频率
});

// 改进同步实体颜色的函数
const synchronizeEntityColors = (editor) => {
  if (!editor || !editor.getBody) {
    console.warn('[实体标注] 无法获取编辑器实例，无法同步实体颜色');
    return;
  }

  console.log('[实体标注] 开始同步实体颜色...');
  const editorBody = editor.getBody();
  if (!editorBody) {
    console.warn('[实体标注] 无法获取编辑器内容，无法同步实体颜色');
    return;
  }

  // 获取所有实体标签
  const entitySpans = editorBody.querySelectorAll('span.entity[data-entity-id]');
  if (entitySpans.length === 0) {
    console.log('[实体标注] 未找到任何实体标签');
    return;
  }

  // 用于收集需要更新的颜色映射，避免多次更新相同实体
  const colorUpdates = {};
  let colorUpdated = 0;

  // 用于规范化颜色值的辅助函数
  const normalizeColor = (colorStr) => {
    if (!colorStr) return '';

    // 处理rgb格式
    if (colorStr.startsWith('rgb')) {
      const rgb = colorStr.match(/\d+/g);
      if (rgb && rgb.length >= 3) {
        return `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;
      }
    }

    // 处理hex格式
    if (colorStr.startsWith('#')) {
      // 将3位hex转换为6位
      if (colorStr.length === 4) {
        const r = colorStr[1];
        const g = colorStr[2];
        const b = colorStr[3];
        return `#${r}${r}${g}${g}${b}${b}`;
      }
      return colorStr.toLowerCase();
    }

    // 返回原始颜色
    return colorStr;
  };

  // 遍历所有实体标签
  entitySpans.forEach(span => {
    const entityId = span.getAttribute('data-entity-id');
    if (!entityId) return;

    // 获取实体类颜色
    const entityColor = editorStore.getEntityColor(entityId);
    if (!entityColor) return;

    // 获取当前背景颜色并标准化
    const currentStyle = span.getAttribute('style') || '';
    const currentColor = normalizeColor(span.style.backgroundColor);
    const targetColor = normalizeColor(entityColor);

    // 比较标准化后的颜色
    if (currentColor !== targetColor) {
      // 创建新的样式字符串，保留除背景色外的其他样式
      let newStyle = '';
      if (currentStyle) {
        // 移除现有的背景色样式
        newStyle = currentStyle.replace(/background-color:[^;]+;?/i, '');
        // 确保以分号结尾
        if (newStyle && !newStyle.endsWith(';')) {
          newStyle += ';';
        }
      }
      // 添加新的背景色样式
      newStyle += `background-color: ${entityColor};`;

      // 更新样式
      span.setAttribute('style', newStyle);

      // 收集更新信息
      colorUpdates[entityId] = entityColor;
      colorUpdated++;
    }
  });

  console.log(`[实体标注] 完成实体颜色同步，已更新 ${colorUpdated} 个实体颜色`);

  // 如果有颜色更新，更新store中的颜色映射并保存内容
  if (colorUpdated > 0) {
    // 更新store中的颜色映射
    editorStore.updateEntityTagColors(colorUpdates);

    // 获取并保存内容
    console.log('[实体标注] 有颜色更新，保存编辑器内容');
    form.content = editor.getContent();
    debouncedSaveContent(form.content);
  }

  return colorUpdated;
};

// 设置自动同步的定时器变量
let colorSyncInterval = null;
// 设置主定时器变量
let timerInterval = null;

// 添加监听实体类数据更新的watch
watch(() => editorStore.entityClasses, (newClasses, oldClasses) => {
  console.log('[实体标注] 检测到实体类数据更新');
  // 当实体类数据更新时，同步实体颜色
  setTimeout(() => {
    const editor = window.tinymce?.get('editor');
    if (editor) {
      synchronizeEntityColors(editor);
    }
  }, 200);
}, { deep: true });
</script>

<style scoped>
.horizontal-container {
  display: flex;
  pointer-events: none;
}

.horizontal-container>div {
  pointer-events: auto;
}

.el-dialog__wrapper {
  background-color: rgba(0, 0, 0, 0.5);
}

.horizontal-container>div:nth-child(1),
.horizontal-container>div:nth-child(3) {
  flex: 1;
}

.horizontal-container>div:nth-child(2) {
  flex: 3;
}

/*中间内容区域*/
.content-area {
  width: 100%;
  height: 625px;
  border: 1px solid #ffffff;
  border-radius: 10px;
  background-color: #ffffff;
  margin-right: 10px;
  margin-top: 20px;
  display: flex;
  flex-direction: column;
}

#editor {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

.tox-toolbar__primary {
  background-color: #c45656;
}

/* 可以添加到全局样式或编辑器内容样式中 */
span.entity[data-checked="true"] {
  border: 1px solid #4CAF50 !important;
  box-shadow: 0 0 2px #4CAF50;
}
</style>
